package net.vkits.anjiamiao.application;

import net.vkits.anjiamiao.domain.model.Address;
import net.vkits.anjiamiao.domain.model.Contract;
import net.vkits.anjiamiao.domain.model.ContractStatus;
import net.vkits.anjiamiao.domain.model.Customer;
import net.vkits.anjiamiao.domain.repository.ContractRepository;
import net.vkits.anjiamiao.domain.repository.CustomerRepository;
import net.vkits.common.storage.StorageService;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.transaction.Transactional;
import java.time.LocalDate;
import java.util.Optional;

/**
 * Created by ethan-liu on 2016/11/12.
 */
@Service
public class ContractApplicationService {
    private static final Logger logger = LoggerFactory.getLogger(ContractApplicationService.class);

    @Resource
    private ContractRepository contractRepository;
    @Resource
    private CustomerRepository customerRepository;
    @Resource
    private StorageService storageService;

    @Transactional
    public void addContract(
                            String landlord,
                            String account,
                            String bank,
                            String cellphone,
                            String phone) {
        Optional<Contract> contractOptional = contractRepository.findByUserPhoneAndDeletedFalse(phone);
        Contract contract = contractOptional.orElse(new Contract());
        contract.setLandlord(landlord);
        contract.setAccount(account);
        contract.setBank(bank);
        contract.setCellphone(cellphone);
        contract.setUserPhone(phone);
        contract.setStatus(ContractStatus.Init);
        contractRepository.save(contract);
    }

    @Transactional
    public void addPhoto(MultipartFile photo, String number, String cellphone) {
        // Handle files
        String originalFilename = photo.getOriginalFilename();
        logger.info("add photo cellphone: {}", cellphone);
        String suffix = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
        String photoUrl = getRandomName(suffix);
        storageService.store(photo, photoUrl);

        Optional<Contract> contractOptional = contractRepository.findByUserPhoneAndDeletedFalse(cellphone);
        contractOptional.ifPresent(contract -> {
            if (number.equals("1")) {
                logger.info("setPhoto1Url: {}", photoUrl);
                contract.setPhoto1Url(photoUrl);
            } else if (number.equals("2")) {
                logger.info("setPhoto2Url: {}", photoUrl);
                contract.setPhoto2Url(photoUrl);
            } else if (number.equals("3")) {
                logger.info("setPhoto3Url: {}", photoUrl);
                contract.setPhoto3Url(photoUrl);
            }
            contract.setStatus(ContractStatus.Init);
            contractRepository.save(contract);
        });
    }

    @Transactional
    public void updateContract(String contractId,
                               Address address,
                               String startDate,
                               String endDate,
                               String status) {
        Contract contract = contractRepository.findOne(Long.parseLong(contractId));
        if (StringUtils.isNotEmpty(startDate)){
            contract.setStartDate(LocalDate.parse(startDate));
        }
        if (StringUtils.isNotEmpty(endDate)){
            contract.setEndDate(LocalDate.parse(endDate));
        }
        contract.setStatus(ContractStatus.valueOf(status));
        contract.setAddress(address);
        contractRepository.save(contract);
    }

    public Optional<Contract> getContract(String cellphone) {
        return contractRepository.findByUserPhoneAndDeletedFalse(cellphone);
    }

    public Contract getContractById(String id) {
        return contractRepository.findOne(Long.parseLong(id));
    }

    public Page<Contract> getContracts(Pageable pageable) {
        return contractRepository.findAll(pageable);
    }

    public Optional<Customer> getCustomerByContractId(String id) {
        Contract contract = contractRepository.findOne(Long.parseLong(id));
        return customerRepository.findByCellPhoneNumAndDeletedFalse(contract.getUserPhone());
    }

    private String getRandomName(String suffix) {
        return RandomStringUtils.randomAlphanumeric(15) + "." + suffix;
    }
}
